package org.demo.model.impl;

import org.demo.model.IModel;

public class FireHoseLoader implements IModel {

	public static final String FH_LOADER = "fh_loader.exe";

	public static final String PARAM_PORT = " --port";

	public static final String PARAM_SEND_XML = " --sendxml";

	public static final String PARAM_SEARCH_PATH = " --search_path";

	public static final String PARAM_NO_PROMPT = " --noprompt";

	public static final String PARAM_SHOW_PERCENTAGE_COMPLETE = " --showpercentagecomplete";

	public static final String PARAM_MEMORY_NAME = " --memoryname";

	public static final String PARAM_CONVERT_PROGRAM_TO_READ = " --convertprogram2read";

	public static final String PARAM_RESET = " --reset";
	
	public static final String PARAM_VERBOSE = " --verbose";

	private final String loader;
	private final String port;
	private final String sendXml;
	private final String patch;
	private final String searchPath;
	private final String memoryName;
	private final boolean useVerbose;
	private final boolean reset;

	private FireHoseLoader(Builder builder) {
		this.loader = builder.loader;
		this.port = builder.port;
		this.sendXml = builder.sendXml;
		this.patch = builder.patch;
		this.searchPath = builder.searchPath;
		this.memoryName = builder.memoryName;
		this.useVerbose = builder.useVerbose;
		this.reset = builder.reset;
	}

	public String getLoader() {
		return loader;
	}

	public String getPort() {
		return port;
	}

	public String getSendXml() {
		return sendXml;
	}

	public String getPatch() {
		return patch;
	}

	public String getSearchPath() {
		return searchPath;
	}

	public String getMemoryName() {
		return memoryName;
	}
	
	public boolean isUseVerbose() {
		return useVerbose;
	}

	public boolean isReset() {
		return reset;
	}

	@Override
	public String cmd() {
		StringBuilder builder = new StringBuilder().append(getLoader()).append(PARAM_PORT).append("=").append("\\\\.\\")
				.append(getPort()).append(PARAM_SEND_XML).append("=").append(getSendXml()).append(PARAM_SEARCH_PATH)
				.append("=").append(getSearchPath()).append(PARAM_NO_PROMPT).append(PARAM_SHOW_PERCENTAGE_COMPLETE)
				.append(PARAM_MEMORY_NAME).append("=").append(getMemoryName()).append(PARAM_CONVERT_PROGRAM_TO_READ);
		if(useVerbose) {
			builder.append(PARAM_VERBOSE);
		}
		if (reset) {
			builder.append(PARAM_RESET);
		}
		return builder.toString();
	}

	public static class Builder {

		private String loader;
		private String port;
		private String sendXml = "rawprogram_unsparse.xml";
		private String patch = "patch0.xml";
		private String searchPath;
		private String memoryName = "EMMC";
		private boolean useVerbose = false;
		private boolean reset = false;

		public Builder loader(String loader) {
			if (loader == null || loader.isEmpty() || !loader.endsWith(FH_LOADER)) {
				throw new IllegalArgumentException("fh_loader can not access!!!");
			}
			if (loader.contains(" ")) {
				this.loader = "\"" + loader + "\"";
			} else {
				this.loader = loader;
			}
			return this;
		}

		public Builder port(String port) {
			if (port == null || port.isEmpty() || !port.contains("COM")) {
				throw new IllegalArgumentException("port can not access!!!");
			}
			this.port = port;
			return this;
		}

		public Builder sendXml(String sendXml) {
			if (sendXml == null || sendXml.isEmpty()) {
				throw new IllegalArgumentException("send xml can not access!!!");
			}
			this.sendXml = sendXml;
			return this;
		}

		public Builder patch(String patch) {
			if (patch == null || patch.isEmpty()) {
				throw new IllegalArgumentException("patch can not access!!!");
			}
			this.patch = patch;
			return this;
		}

		public Builder searchPath(String searchPath) {
			if (searchPath == null || searchPath.isEmpty()) {
				throw new IllegalArgumentException("search path can not access!!!");
			}
			this.searchPath = searchPath;
			return this;
		}

		public Builder memoryName(String memoryName) {
			if (memoryName == null || memoryName.isEmpty()) {
				throw new IllegalArgumentException("memory name can not access!!!");
			}
			if (!memoryName.toLowerCase().trim().equals("emmc") && !memoryName.toLowerCase().trim().equals("ufs")) {
				throw new IllegalArgumentException("memory name can not resolve!!!");
			}
			this.memoryName = memoryName;
			return this;
		}
		
		public Builder useVerbose(boolean use) {
			this.useVerbose = use;
			return this;
		}
		
		public Builder reset(boolean reset) {
			this.reset = reset;
			return this;
		}

		public FireHoseLoader build() {
			return new FireHoseLoader(this);
		}

	}

}
